package com.ds.lens.data.service;

import com.github.pagehelper.Page;
import com.google.common.base.CaseFormat;
import com.google.common.base.Converter;
import com.ds.lens.data.common.asserts.Asserts;
import com.ds.lens.data.common.constant.Constants;
import com.ds.lens.data.service.dao.LensDashboardDao;
import com.ds.lens.data.service.dao.entity.LensDashboard;
import com.ds.lens.data.service.dao.entity.LensDashboardFavorite;
import com.ds.lens.data.vo.in.PagedConditionInVO;
import com.ds.lens.data.vo.in.Sort;
import com.ds.lens.data.vo.in.User;
import com.ds.lens.data.vo.in.v2.dashboard.LensDashboardInVO;
import com.ds.lens.data.vo.in.v2.dashboard.LensDashboardListInVO;
import com.ds.lens.data.vo.out.PageResult;
import com.ds.lens.data.vo.out.v2.dashboard.LensDashboardOutVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author WeiShaoying
 * @date 2019/11/6 下午2:37
 */
@Slf4j
@Service
public class LensDashboardService extends BaseService {


    @Autowired
    LensDashboardDao lensDashboardDao;
    //驼峰转下划线
    private Converter<String, String> camelToUnderscoreConverter = CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.LOWER_UNDERSCORE);


    public PageResult<LensDashboardOutVO> queryDashboard(PagedConditionInVO<LensDashboardListInVO> conditionInVO, User user) {
        getPageCondition(conditionInVO);
        if (CollectionUtils.isEmpty(conditionInVO.getCondition().getApplicationIds())) {
            checkUserApplication(user);
            conditionInVO.getCondition().setApplicationIds(user.getApplicationIds());
        } else {
            checkUserApplication(user, conditionInVO.getCondition().getApplicationIds());
        }

        if(conditionInVO.getSort() == null){
            Sort sort = new Sort();
            sort.setField("modified_time");
            sort.setOrder(Sort.ORDER_DESC);
            conditionInVO.setSort(sort);

        }
        if( "favorite".equals(conditionInVO.getSort().getField())){
            conditionInVO.getSort().setField("f.dashboard_id");

        }
        conditionInVO.getSort().setField(camelToUnderscoreConverter.convert(conditionInVO.getSort().getField()));
        conditionInVO.getCondition().setSort(conditionInVO.getSort());
        Page<LensDashboard> page = lensDashboardDao.queryDashboard(conditionInVO.getCondition(), user.getUsername());
        List<LensDashboardOutVO> lensDashboardOutVOS = new ArrayList<>(page.getPageSize());

        if (CollectionUtils.isEmpty(page.getResult())) {
            return PageResult.of(Collections.emptyList(), 0L, page.getPageNum(), page.getPageSize());
        }

        //添加收藏信息
        Map<String, LensDashboardFavorite> temp = new HashMap<>();
        List<LensDashboardFavorite> lensDashboardFavorites = lensDashboardDao.queryFavoriteList(user.getUsername());
        if(!CollectionUtils.isEmpty(lensDashboardFavorites)){
            for (LensDashboardFavorite lensDashboardFavorite : lensDashboardFavorites
                 ) {
                temp.put(lensDashboardFavorite.getDashboardId().toString(),lensDashboardFavorite);
            }
        }
        for(LensDashboard lensDashboard : page.getResult()){
            LensDashboardOutVO lensDashboardOutVO = new LensDashboardOutVO();
            BeanUtils.copyProperties(lensDashboard, lensDashboardOutVO);
            lensDashboardOutVO.setCreatedTime(lensDashboard.getCreatedTime().getTime());
            lensDashboardOutVO.setModifiedTime(lensDashboard.getModifiedTime().getTime());
            if(temp.containsKey(lensDashboardOutVO.getId().toString())){
                lensDashboardOutVO.setFavorite(1L);
            }
            lensDashboardOutVOS.add(lensDashboardOutVO);
        }
//        if("favorite".equals(conditionInVO.getSort().getField())){
//            //排序
//            if(conditionInVO.getSort().getOrder().equals(conditionInVO.getSort().ORDER_ASC)){
//                Collections.sort(lensDashboardOutVOS, new MySort());
//
//            }else {
//                Comparator descComparator = Collections.reverseOrder(new MySort());
//                Collections.sort(lensDashboardOutVOS,descComparator);
//            }
//        }
        return PageResult.of(lensDashboardOutVOS, page.getTotal(), page.getPageNum(), page.getPageSize());
    }

    //比较器类
    static class MySort implements Comparator{
        @Override
        public int compare(Object o1, Object o2){
            LensDashboardOutVO p1 = (LensDashboardOutVO)o1;
            LensDashboardOutVO p2 = (LensDashboardOutVO)o2;
            //升序
            return Integer.parseInt(p1.getFavorite().toString()) - Integer.parseInt(p2.getFavorite().toString());
        }
    }

    public LensDashboardOutVO getDashboardDetail(Long id, User user){
        LensDashboard lensDashboard = lensDashboardDao.selectByPrimaryKey(id);
        if(lensDashboard == null){
            return null;
        }
        LensDashboardOutVO lensDashboardOutVO = new LensDashboardOutVO();
        BeanUtils.copyProperties(lensDashboard, lensDashboardOutVO);
        lensDashboardOutVO.setCreatedTime(lensDashboard.getCreatedTime().getTime());
        lensDashboardOutVO.setModifiedTime(lensDashboard.getModifiedTime().getTime());
        //添加收藏信息
        int flag = lensDashboardDao.isCollected(id, user.getUsername());
        if(flag>0){
            lensDashboardOutVO.setFavorite(1L);
        }

        //处理打开数
        addOpenedCount(id, user);

        return lensDashboardOutVO;
    }

    public Boolean addFavorite(Long id, User user){
        try{
            lensDashboardDao.saveFavorite(id, user.getUsername());
            return true;
        }catch (Exception e ){
            log.error("addFavorite error:",e);
            return false;
        }

    }

    public Boolean addOpenedCount(Long id, User user){
        try{
            lensDashboardDao.addOpenedCount(user.getUsername(), id);
            return true;
        }catch (Exception e ){
            log.error("addOpenedCount error:",e);
            return false;
        }

    }

    public Boolean share(Long id, User user){
        try{
            lensDashboardDao.shareDashboard(id, 1, user.getUsername());
            return true;
        }catch (Exception e ){
            log.error("share error:",e);
            return false;
        }

    }

    public Boolean unshare(Long id, User user){
        try{
            lensDashboardDao.shareDashboard(id, 0, user.getUsername());
            return true;
        }catch (Exception e ){
            log.error("unshare error:",e);
            return false;
        }

    }

    public Long saveDashboard(LensDashboardInVO lensDashboardInVO, User user){
        if(lensDashboardInVO.getType() == 2){
            Asserts.assertFalse(StringUtils.isEmpty(lensDashboardInVO.getMonitorId()) ||
                    StringUtils.isEmpty(lensDashboardInVO.getMonitorVersion()), Constants.ErrorCode.DASHBOARD_MONITOR_INFO_NULL);
        }

        try{
            //如果是事件，则判断当前用户是否已经创建过
            if(lensDashboardInVO.getType() == 2){
                LensDashboard exists = lensDashboardDao.isExists(user.getUsername(), lensDashboardInVO.getEventId());
                if(exists != null){
                    return exists.getId();
                }

            }
            LensDashboard lensDashboard = new LensDashboard();
            BeanUtils.copyProperties(lensDashboardInVO, lensDashboard);
            if(lensDashboard.getType() == 2 && lensDashboard.getExpertTemplate() != null &&  lensDashboard.getExpertTemplate() == 1){//事件类型，同时为专家模板
                lensDashboard.setOpenedCount(100);
            }else {
                lensDashboard.setOpenedCount(0);
            }

            lensDashboard.setCreatedTime(new Date());
            lensDashboard.setCreator(user.getUsername());
            lensDashboard.setMender(lensDashboard.getCreator());
            lensDashboard.setModifiedTime(lensDashboard.getCreatedTime());
            lensDashboardDao.insertSelective(lensDashboard);
            return lensDashboard.getId();
        }catch (Exception e ){
            log.error("saveDashboard error:",e);
            return -1L;
        }
    }

    public Boolean updateDashboard(LensDashboardInVO lensDashboardInVO, User user){
        try{
            LensDashboard lensDashboard = new LensDashboard();
            BeanUtils.copyProperties(lensDashboardInVO, lensDashboard);
            //判断专家模板
            LensDashboard oldLensDashboard = lensDashboardDao.selectByPrimaryKey(lensDashboard.getId());
            Asserts.assertTrue(oldLensDashboard != null, Constants.ErrorCode.SYSTEM_EXCEPTION);
            if(lensDashboard.getType() == 2 && oldLensDashboard.getExpertTemplate() == 1){
                if(lensDashboard.getExpertTemplate() == 0){
                    lensDashboard.setOpenedCount(oldLensDashboard.getOpenedCount() - 100);
                }
            }else if(lensDashboard.getType() == 2 && oldLensDashboard.getExpertTemplate() == 0){
                if(lensDashboard.getExpertTemplate() == 1){
                    lensDashboard.setOpenedCount(oldLensDashboard.getOpenedCount() + 100);
                }
            }
            lensDashboard.setMender(user.getUsername());
            lensDashboard.setModifiedTime(new Date());
            Asserts.assertTrue(lensDashboardDao.updateByPrimaryKeySelective(lensDashboard) == 1, Constants.ErrorCode.SYSTEM_EXCEPTION);
            return true;
        }catch (Exception e ){
            log.error("updateDashboard error:",e);
            return false;
        }
    }

    @Transactional
    public Boolean deleteDashboard(List<Long> ids, User user){

        lensDashboardDao.deleteDashboard(ids, user.getUsername());
        lensDashboardDao.removeFavorite(ids, null);

        return true;
    }


    public Boolean removeFavorite(Long id, User user){
        try{
            List<Long> ids = new ArrayList<>();
            ids.add(id);
            lensDashboardDao.removeFavorite(ids, user.getUsername());
            return true;
        }catch (Exception e ){
            log.error("removeFavorite error:",e);
            return false;
        }

    }

    public PageResult<LensDashboardOutVO> getRecommendedDashboard(PagedConditionInVO<LensDashboardListInVO> conditionInVO, User user) {
        Asserts.assertFalse(StringUtils.isEmpty(conditionInVO.getCondition().getMonitorId()), Constants.ErrorCode.DASHBOARD_MONITOR_ID_NULL);

        getPageCondition(conditionInVO);
        if (CollectionUtils.isEmpty(conditionInVO.getCondition().getApplicationIds())) {
            checkUserApplication(user);
            conditionInVO.getCondition().setApplicationIds(user.getApplicationIds());
        } else {
            checkUserApplication(user, conditionInVO.getCondition().getApplicationIds());
        }

        if(conditionInVO.getSort() == null){
            conditionInVO.getCondition().setSort(null);
        }else{
            conditionInVO.getSort().setField(camelToUnderscoreConverter.convert(conditionInVO.getSort().getField()));
            conditionInVO.getCondition().setSort(conditionInVO.getSort());
        }

        Page<LensDashboard> page = lensDashboardDao.queryRecommendedDashboard(conditionInVO.getCondition(), user.getUsername());
        List<LensDashboardOutVO> lensDashboardOutVOS = new ArrayList<>(page.getPageSize());

        if (CollectionUtils.isEmpty(page.getResult())) {
            return PageResult.of(Collections.emptyList(), 0L, page.getPageNum(), page.getPageSize());
        }

        //添加收藏信息
        Map<String, LensDashboardFavorite> temp = new HashMap<>();
        List<LensDashboardFavorite> lensDashboardFavorites = lensDashboardDao.queryFavoriteList(user.getUsername());
        if(!CollectionUtils.isEmpty(lensDashboardFavorites)){
            for (LensDashboardFavorite lensDashboardFavorite : lensDashboardFavorites
            ) {
                temp.put(lensDashboardFavorite.getDashboardId().toString(),lensDashboardFavorite);
            }
        }
        for(LensDashboard lensDashboard : page.getResult()){
            LensDashboardOutVO lensDashboardOutVO = new LensDashboardOutVO();
            BeanUtils.copyProperties(lensDashboard, lensDashboardOutVO);
            lensDashboardOutVO.setCreatedTime(lensDashboard.getCreatedTime().getTime());
            lensDashboardOutVO.setModifiedTime(lensDashboard.getModifiedTime().getTime());
            if(temp.containsKey(lensDashboardOutVO.getId().toString())){
                lensDashboardOutVO.setFavorite(1L);
            }
            lensDashboardOutVOS.add(lensDashboardOutVO);
        }
        return PageResult.of(lensDashboardOutVOS, page.getTotal(), page.getPageNum(), page.getPageSize());
    }


}
